(deftemplate father-of (slot father) (slot child))
(deftemplate mother-of (slot mother) (slot child))
(deftemplate male (slot person))
(deftemplate female (slot person))
(deftemplate wife-of (slot wife) (slot husband))
(deftemplate husband-of (slot husband) (slot wife))

(deftemplate find_grandfather(slot name))
(deftemplate find_grandmother(slot name))
(deftemplate find_grandparent(slot name))
(deftemplate find_sister(slot name))
(deftemplate find_brother(slot name))
(deftemplate find_uncle(slot name))
(deftemplate find_ancestor(slot name))

(deffacts relations
	(male(person ma1))
	(male(person mb1))
	(male(person ma21))
	(male(person ma22))
	(male(person mb21))
	(male(person mb22))
	(male(person mc31))
	(male(person mc32))
	(male(person md31))
	(male(person md32))

	(female(person fma2))
	(female(person fmb2))
	(female(person fma23))
	(female(person fma24))
	(female(person fmb23))
	(female(person fmb24))
	(female(person fmd33))
	(female(person fmd34))
	(female(person fmc33))
	(female(person fmc34))
	
	(father-of(father ma1)(child ma21))
	(father-of(father ma1)(child ma22))
	(father-of(father ma1)(child fma23))
	(father-of(father ma1)(child fma24))

	(mother-of(mother fma2)(child ma21))
	(mother-of(mother fma2)(child ma22))
	(mother-of(mother fma2)(child fma23))
	(mother-of(mother fma2)(child fma24))

	(father-of(father mb1)(child mb21))
	(father-of(father mb1)(child mb22))
	(father-of(father mb1)(child fmb23))
	(father-of(father mb1)(child fmb24))

	(mother-of(mother fmb2)(child mb21))
	(mother-of(mother fmb2)(child mb22))
	(mother-of(mother fmb2)(child fmb23))
	(mother-of(mother fmb2)(child fmb24))
	
	(father-of(father mb21)(child mc31))
	(father-of(father mb21)(child mc32))
	(father-of(father mb21)(child fmc33))
	(father-of(father mb21)(child fmc34))
	
	(mother-of(mother fma24)(child mc31))
	(mother-of(mother fma24)(child mc32))
	(mother-of(mother fma24)(child fmc33))
	(mother-of(mother fma24)(child fmc34))

	(father-of(father ma21)(child md31))
	(father-of(father ma21)(child md32))
	(father-of(father ma21)(child fmd33))
	(father-of(father ma21)(child fmd34))

	(mother-of(mother fmb23)(child md31))
	(mother-of(mother fmb23)(child md32))
	(mother-of(mother fmb23)(child fmd33))
	(mother-of(mother fmb23)(child fmd34))


	(wife-of(wife fma2)(husband ma1))
	(wife-of(wife fmb2)(husband mb1))
	(wife-of(wife fmb23)(husband ma21))
	(wife-of(wife fma24)(husband mb21))

	(husband-of(husband ma1)(wife fma2))
	(husband-of(husband mb1)(wife fmb2))
	(husband-of(husband ma21)(wife fmb23))
	(husband-of(husband mb21)(wife fma24))
)

(defrule find_gf
	(find_grandfather(name ?name))
	(or
		(father-of(father ?p)(child ?name))
		(mother-of(mother ?p)(child ?name))
	)
	(father-of(father ?gp)(child ?p))
	=>(printout t ?gp " is " ?name "'s grandfather." crlf)
)

(defrule find_gm
	(find_grandmother (name ?name))
	(or
		(father-of(father ?p)(child ?name))
		(mother-of(mother ?p)(child ?name))
	)
	(mother-of(mother ?gp)(child ?p))
	=>(printout t ?gp " is " ?name "'s grandmother." crlf)
)

(defrule find_gp
	(find_grandparent (name ?name))
    
	(or
		(father-of(father ?p)(child ?name))
		(mother-of(mother ?p)(child ?name))
	)
	(or
		(father-of(father ?gp)(child ?p))
		(mother-of(mother ?gp)(child ?p))
	)
	=>(printout t ?gp " is " ?name "'s grandparent." crlf)
)

(defrule find_s	
	(find_sister (name ?name))
	(or
		(father-of(father ?p)(child ?name))
		(mother-of(mother ?p)(child ?name))
	)
	(or
		(father-of(father ?p)(child ?f&~?name))
		(mother-of(mother ?p)(child ?f&~?name))
	)
	(female(person ?f))
	=>(printout t ?f " is " ?name "'s sister." crlf)
)

(defrule find_b	
	(find_brother (name ?name))
	(or
		(father-of(father ?p)(child ?name))
		(mother-of(mother ?p)(child ?name))
	)
	(or
		(father-of(father ?p)(child ?f&~?name))
		(mother-of(mother ?p)(child ?f&~?name))
	)
	(male(person ?f))
	=>(printout t ?f " is " ?name "'s brother." crlf)
)

(defrule find_un		
	(find_uncle (name ?name))
	(or
		(father-of(father ?p)(child ?name))
		(mother-of(mother ?p)(child ?name))
	)
	(or
		(father-of(father ?gp)(child ?p))
		(mother-of(mother ?gp)(child ?p))
	)
	(or
		(father-of(father ?gp)(child ?ap&~?p))
		(mother-of(mother ?gp)(child ?ap&~?p))
	)
	(or
		(male(person ?ucl&?ap))
		(and
			(female(person ?ap))
			(husband-of(husband ?ucl&~?p)(wife ?ap))
		)
	)
	=>
	(printout t ?ucl " is " ?name "'s uncle" crlf)
)

(defrule find_an
	?pre<-(find_ancestor(name ?name))
		(mother-of(mother ?mp)(child ?name))
		(father-of(father ?fp)(child ?name))
	=>
	(printout t ?mp " is his/her ancestor" crlf)
	(printout t ?fp " is his/her ancestor" crlf)
	(retract ?pre)
	(assert(find_ancestor(name ?mp)))
	(assert(find_ancestor(name ?fp)))
)